import { path } from 'ramda';
import set from 'lodash/set';

import { gqcPermissionCheck } from '@kuiper/auth';
import { dealWithBalanceGQCMiddleware } from '../plugins/billing';
import findByIdsEmpty from './Job/findByIdsEmpty';

export default server => {
	const {
		app: {
			model: { Whitelist },
		},
	} = server;

	server.methods.registerGraphQLSchema({
		name: 'Whitelist',
		model: Whitelist,
		queryFields: {
			One: 'findOne',
			Pagination: 'pagination',
			Count: 'count',
		},
		mutationFields: {
			CreateOne: 'createOne',
			UpdateOne: 'updateOne',
			RemoveMany: 'removeMany',
			RemoveOne: 'removeOne',
		},
		onPreAddFields(tc) {
			const {
				app: {
					graphqlResolvers,
					schema: { Job, User },
				},
			} = server;

			tc.mongooseResolvers
				.findMany()
				.args.filter.type.setField('taskTypes', 'String');
			tc.mongooseResolvers
				.count()
				.args.filter.type.setField('taskTypes', 'String');
			tc.mongooseResolvers
				.findMany()
				.args.filter.type.setField('jobIds', 'MongoID');
			tc.mongooseResolvers
				.count()
				.args.filter.type.setField('jobIds', 'MongoID');

			tc.addRelation('user', {
				resolver: () => User.mongooseResolvers.dataLoader({ lean: true }),
				prepareArgs: {
					_id: source => source.uid,
				},
				projection: { uid: 1 },
			});

			tc.addRelation('job', {
				resolver: () =>
					Job.mongooseResolvers
						.dataLoaderMany({ lean: true })
						.wrapResolve(findByIdsEmpty),
				prepareArgs: {
					_ids: source => source.jobIds.filter(Boolean),
				},
				projection: { jobIds: 1 },
			});

			const listPermissionCheck = gqcPermissionCheck({
				required: 'cloud-monitor\x01listWhitelist',
				selfOnlyArgsBuilder: (_source, args, context) => {
					const uid = path(['request', 'auth', 'credentials', 'uid'], context);
					set(args, ['filter', 'uid'], uid);
				},
			});
			graphqlResolvers.Query.WhitelistPagination = graphqlResolvers.Query.WhitelistPagination.withMiddlewares(
				[listPermissionCheck]
			);
			graphqlResolvers.Query.WhitelistOne = graphqlResolvers.Query.WhitelistOne.withMiddlewares(
				[listPermissionCheck]
			);
			graphqlResolvers.Query.WhitelistCount = graphqlResolvers.Query.WhitelistCount.withMiddlewares(
				[listPermissionCheck]
			);

			graphqlResolvers.Mutation.WhitelistCreateOne = graphqlResolvers.Mutation.WhitelistCreateOne.withMiddlewares(
				[
					gqcPermissionCheck({
						required: 'cloud-monitor\x01editWhitelist',
						selfOnlyArgsBuilder: (_source, args, context) => {
							const uid = path(
								['request', 'auth', 'credentials', 'uid'],
								context
							);
							set(args, ['record', 'uid'], uid);
						},
					}),
					dealWithBalanceGQCMiddleware((root, args, context) => ({
						server: context.request.server,
						uid: args.record.uid,
						ops: [
							{
								key: 'whitelist',
								value: -1,
							},
						],
					})),
				]
			);
			graphqlResolvers.Mutation.WhitelistUpdateOne = tc.mongooseResolvers
				.updateOne()
				.withMiddlewares([
					gqcPermissionCheck({
						required: 'cloud-monitor\x01editWhitelist',
						selfOnlyArgsBuilder: (_source, args, context) => {
							const uid = path(
								['request', 'auth', 'credentials', 'uid'],
								context
							);
							set(args, ['filter', 'uid'], uid);
						},
					}),
				]);
			graphqlResolvers.Mutation.WhitelistRemoveMany = graphqlResolvers.Mutation.WhitelistRemoveMany.withMiddlewares(
				[
					gqcPermissionCheck({
						required: 'cloud-monitor\x01editWhitelist',
						selfOnlyArgsBuilder: (_source, args, context) => {
							const uid = path(
								['request', 'auth', 'credentials', 'uid'],
								context
							);
							set(args, ['filter', 'uid'], uid);
						},
					}),
					dealWithBalanceGQCMiddleware((root, args, context) => ({
						server: context.request.server,
						uid: args.filter.uid,
						ops: [
							{
								key: 'whitelist',
								value: 1,
							},
						],
						beforeCalc({ ops, response }) {
							ops[0].value *= response.numAffected;
						},
					})),
				]
			);
			graphqlResolvers.Mutation.WhitelistRemoveOne = graphqlResolvers.Mutation.WhitelistRemoveOne.withMiddlewares(
				[
					gqcPermissionCheck({
						required: 'cloud-monitor\x01editWhitelist',
						selfOnlyArgsBuilder: (_source, args, context) => {
							const uid = path(
								['request', 'auth', 'credentials', 'uid'],
								context
							);
							set(args, ['filter', 'uid'], uid);
						},
					}),
					dealWithBalanceGQCMiddleware((root, args, context) => ({
						server: context.request.server,
						uid: args.filter.uid,
						ops: [
							{
								key: 'whitelist',
								value: 1,
							},
						],
					})),
				]
			);
		},
	});
};
